﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web;
using System.Text;

namespace Gx.Common
{
    /// <summary>
    /// 数据类型扩展
    /// </summary>
    public static class DataTypeExtensions
    {
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool ExistsString(string value)
        {
            string[] word = { "<", ">", "?", "'", "！", "!", "~", "@", "￥",
                "%", "《", "》", "and", "exec", "insert", "select", "delete",
                "update", "chr", "mid", "master", "or", "truncate", "char", "declare", "join" };
            foreach (var item in word)
            {
                if (value.ToLower().Contains(item))
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 是否为空
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string value)
        {
            return string.IsNullOrEmpty(value) ? true : ExistsString(value);
        }

        /// <summary>
        /// 格式化时间格式 yyyy-MM-dd HH:mm:ss
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToStringyyyyMMddHHmmss(this DateTime dt)
        {
            return !dt.IsDate() ? "" : dt.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// 格式化时间格式 yyyyMMddHHmmssfff
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToStringyyyyMMddHHmmfff(this DateTime dt)
        {
            return !dt.IsDate() ? "" : dt.ToString("yyyyMMddHHmmssfff");
        }

        /// <summary>
        /// 格式化时间格式 yyyyMMddHHmmssfff
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="joinStr"></param>
        /// <returns></returns>
        public static string ToStringyyyyMMddHHmmfff(this DateTime dt, string joinStr)
        {
            return !dt.IsDate() ? "" : joinStr + dt.ToString("yyyyMMddHHmmssfff");
        }

        /// <summary>
        /// 格式化时间格式 年月日
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToStringyyyyMMdd(this DateTime dt)
        {
            return !dt.IsDate() ? "" : dt.ToString("yyyy-MM-dd");
        }

        /// <summary>
        /// 格式化时间格式 2017-01-01 00:00:00
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToStringyyyyMMdd000000(this DateTime dt)
        {
            return !dt.IsDate() ? "" : dt.ToString("yyyy-MM-dd 00:00:00");
        }

        /// <summary>
        /// 格式化时间格式 2017-01-01 23:59:59
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToStringyyyyMMdd235959(this DateTime dt)
        {
            return !dt.IsDate() ? "" : dt.ToString("yyyy-MM-dd 23:59:59");
        }

        /// <summary>
        /// 截取字符串
        /// </summary>
        /// <param name="str"></param>
        /// <param name="length"></param>
        /// <param name="chars"></param>
        /// <returns>returns>
        public static string subString(this string oldValue, int length, string chars)
        {
            if (string.IsNullOrEmpty(oldValue))
                return string.Empty;
            if (oldValue.Length > length)
                return oldValue.Substring(0, length) + chars;
            return oldValue;
        }

        /// <summary>
        /// 截取字符串
        /// </summary>
        /// <param name="str"></param>
        /// <param name="length"></param>
        /// <param name="chars"></param>
        /// <returns>返回......</returns>
        public static string subString(this string oldValue, int length)
        {
            if (string.IsNullOrEmpty(oldValue))
                return string.Empty;
            if (oldValue.Length > length)
                return oldValue.Substring(0, length) + "...";
            return oldValue;
        }

        /// <summary>
        /// 清除文件HTML格式函数
        /// </summary>
        /// <param name="sBody"></param>
        /// <returns></returns>
        public static string ClearHtml(this string sBody)
        {
            if (string.IsNullOrEmpty(sBody))
            {
                return "";
            }
            sBody = sBody.Replace("&lt;", "<");
            sBody = sBody.Replace("&gt;", ">");
            sBody = sBody.Replace("&amp;", "&");
            sBody = sBody.Replace("&nbsp;", "");
            sBody = sBody.Replace("&quot;", "&");
            sBody = sBody.Replace("&ldquo;", "“");
            sBody = sBody.Replace("&rdquo;", "”");
            sBody = sBody.Replace("hellip;", "…");
            sBody = sBody.Replace("mdash;", "——");
            sBody = sBody.Replace("middot;", "·");
            sBody = sBody.Replace("&times;", "×");
            sBody = sBody.Replace("&divide;", "÷");
            sBody = sBody.Replace("    ", "");  //替换制表符Tab为空
            // sBody = sBody.Replace(Chr(13), ",");
            // sBody = sBody.Replace(Chr(10), ",");
            sBody = ReplaceHtml("&#[^>]*;", "", sBody);
            sBody = ReplaceHtml("</?marquee[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?object[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?param[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?embed[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?table[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?tr[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?th[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?p[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?a[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?img[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?tbody[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?li[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?span[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?div[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?th[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?td[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?script[^>]*>", "", sBody);
            sBody = ReplaceHtml("(javascript|jscript|vbscript|vbs):", "", sBody);
            sBody = ReplaceHtml("on(mouse|exit|error|click|key)", "", sBody);
            sBody = ReplaceHtml("<\\?xml[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?[a-z]+:[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?font[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?b[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?u[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?i[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?strong[^>]*>", "", sBody);
            sBody = ReplaceHtml("</?st1:chsdate[^>]*>,", "", sBody);
            sBody = ReplaceHtml("<[^>]+>", "", sBody);
            sBody = ClearSpecialContent(sBody);
            return sBody;
        }

        /// <summary>
        /// 解码
        /// </summary>
        /// <param name="body"></param>
        /// <returns></returns>
        public static string UrlDecode(this string body)
        {
            return HttpUtility.UrlDecode(body);
        }

        /// <summary>
        /// 编码
        /// </summary>
        /// <param name="body"></param>
        /// <returns></returns>
        public static string UrlEncode(this string body)
        {
            return HttpUtility.UrlEncode(body);
        }


        /// <summary>
        /// 清除HTML内容中的特殊内容
        /// </summary>
        /// <param name="sBody"></param>
        /// <returns></returns>
        private static string ClearSpecialContent(string sBody)
        {
            sBody = sBody.Replace("&", "");
            sBody = sBody.Replace("\"urn:schemas-microsoft-com:office:smarttags\" />", "");
            sBody = sBody.Replace("<st1:chsda...>", "");
            sBody = sBody.Replace("<?xml", "");
            sBody = sBody.Replace("/>", "");
            sBody = sBody.Replace(">", "");
            sBody = sBody.Replace("<", "");
            sBody = sBody.Replace(":namespace", "");
            sBody = sBody.Replace("urn:schemas-microsoft", "");
            sBody = sBody.Replace("prefix =", "");
            sBody = sBody.Replace("ns =", "");
            sBody = sBody.Replace("com:office:office", "");
            sBody = sBody.Replace("\"-\"", "");
            sBody = sBody.Replace(",,", "");
            sBody = sBody.Replace(",,", "");
            return sBody;
        }

        // <summary>
        /// 正则匹配(正则表达式)模式进行数据匹配替换
        /// </summary>
        /// <param name="sPattern"></param>
        /// <param name="sReplace"></param>
        /// <param name="sBody"></param>
        /// <returns></returns>
        private static string ReplaceHtml(string sPattern, string sReplace, string sBody)
        {
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(sPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            sBody = reg.Replace(sBody, sReplace);
            return sBody;
        }

        /// <summary>
        /// 是否是单经度Decimal类型
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsDecimal(this string str)
        {
            return decimal.TryParse(str, out decimal test);
        }
        /// <summary>
        /// 是否是单精度Decimal类型,并返回Decimal
        /// </summary>
        /// <param name="str"></param>
        /// <param name="test"></param>
        /// <returns></returns>
        public static bool IsDecimal(this string str, out decimal test)
        {
            return decimal.TryParse(str, out test);
        }

        /// <summary>
        /// 双精度
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsDouble(this string str)
        {
            return double.TryParse(str, out double test);
        }

        /// <summary>
        /// 是否是双精度double类型,并返回double
        /// </summary>
        /// <param name="str"></param>
        /// <param name="test"></param>
        /// <returns></returns>
        public static bool IsDouble(this string str, out double test)
        {
            return double.TryParse(str, out test);
        }

        /// <summary>
        /// 是否是int
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsInt(this string str)
        {
            return int.TryParse(str, out int test);
        }

        /// <summary>
        /// 是否是int类型,并返回
        /// </summary>
        /// <param name="str"></param>
        /// <param name="test"></param>
        /// <returns></returns>
        public static bool IsInt(this string value, out int value1)
        {
            return int.TryParse(value, out value1);
        }

        /// <summary>
        /// 是否object
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsObject(this object value)
        {
            return value == null ? false : true;
        }

        /// <summary>
        /// 转换成INT类型
        /// </summary>
        /// <param name="value"></param>
        /// <returns>转行失败则是0</returns>
        public static int IntParse(this object value)
        {
            string obj = value == null ? "" : value.ToString();
            return IsInt(obj) ? int.Parse(obj) : 0;
        }

        /// <summary>
        /// 转换成INT类型
        /// </summary>
        /// <param name="value"></param>
        /// <returns>转行失败则是0</returns>
        public static int IntParse(this string value)
        {
            return IsInt(value) ? int.Parse(value) : 0;
        }

        /// <summary>
        /// 是否是IsDateTime类型,并返回
        /// </summary>
        /// <param name="str"></param>
        /// <param name="test"></param>
        /// <returns></returns>
        public static bool IsDateTime(this string str)
        {
            DateTime dt = DateTime.Now;
            return DateTime.TryParse(str, out dt);
        }

        public static bool IsDate(this DateTime s)
        {
            return s.Year == 1911 || s == DateTime.MinValue ? false : true;
        }

        public static bool IsDate(this DateTime? s)
        {
            return s == null ? false : true;
        }

        /// <summary>
        /// 是否是IsDateTime类型,并返回
        /// </summary>
        /// <param name="str"></param>
        /// <param name="test"></param>
        /// <returns></returns>
        public static bool IsDateTime(this string str, out DateTime test)
        {
            return DateTime.TryParse(str, out test);
        }

        public static DateTime DateTimeParse(this string value)
        {
            return DateTime.Parse(value);
        }

        public static string ToStringf2(this decimal str, string text = "f2")
        {
            return str.ToString(text);
        }
        public static string ToStringf3(this decimal str)
        {
            return str.ToString("f3");
        }

        public static string ToStringf4(this decimal str)
        {
            return str.ToString("f4");
        }
        /// <summary>
        /// 空值或者小于等于指定的值返回ture
        /// </summary>
        /// <param name="value"></param>
        /// <returns>空值或者小于等于指定的值</returns>
        public static bool IsNull(this int? value)
        {
            return value == null ? true : false;
        }

        /// <summary>
        /// 空值或者小于等于指定的值返回ture
        /// </summary>
        /// <param name="value"></param>
        /// <param name="value1"></param>
        /// <returns>空值或者小于等于指定的值,否则false</returns>
        public static bool IsNull(this int? value, int value1)
        {
            return value == null || value.Value <= value1 ? true : false;
        }

        public static bool IsNull(this bool? value)
        {
            return value == null ? true : false;
        }
        public static bool IsNull(this byte? value)
        {
            return value == null ? true : false;
        }

        /// <summary>
        /// 默认以,号分隔开
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string[] split(this string value)
        {
            if (value == null)
            {
                return new string[] { "0" };
            }
            return value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        }

        /// <summary>
        /// 切割字符成数组
        /// </summary>
        /// <param name="value"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
        public static string[] split(this string value, char separator)
        {
            if (value == null)
            {
                return new string[] { "0" };
            }
            return value.Split(new char[] { separator }, StringSplitOptions.RemoveEmptyEntries);
        }

        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static long GetTimestamp(this DateTime dt)
        {
            TimeSpan ts = dt.ToUniversalTime() - new DateTime(1970, 1, 1);//ToUniversalTime()转换为标准时区的时间,去掉的话直接就用北京时间
            // return (long)ts.TotalMilliseconds; //精确到毫秒
            return (long)ts.TotalSeconds;//获取10位
        }

        /// <summary>
        /// 前三后四中间用****显示
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string MobileRegex(this string value)
        {
            return Regex.Replace(value, "(\\d{3})\\d{4}(\\d{4})", "$1****$2");
        }


        /// <summary>
        /// 前三后四中间用****显示
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string CardRegex(this string value)
        {
            return Regex.Replace(value, "(\\d{3})\\d{11}(\\d{4})", "$1***********$2");
        }

        /// <summary>
        /// 根据年月日计算星期几(Label2.Text=CaculateWeekDay(2004,12,9);)
        /// </summary>
        /// <param name="value">当前时间</param>
        /// <returns></returns>
        public static string CaculateWeekDay(this DateTime value)
        {
            int y = value.Year, m = value.Month, d = value.Day;
            if (m == 1) m = 13;
            if (m == 2) m = 14;
            int week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7 + 1;
            string weekstr = "";
            switch (week)
            {
                case 1: weekstr = "星期一"; break;
                case 2: weekstr = "星期二"; break;
                case 3: weekstr = "星期三"; break;
                case 4: weekstr = "星期四"; break;
                case 5: weekstr = "星期五"; break;
                case 6: weekstr = "星期六"; break;
                case 7: weekstr = "星期日"; break;
            }
            return weekstr;
        }



        public static string Join(this List<string> s)
        {
            if (s == null || s.Count == 0)
            {
                return "'0'";
            }
            StringBuilder sb = new StringBuilder();
            foreach (var item in s)
            {
                if (sb.Length > 0)
                {
                    sb.Append(",");
                }
                sb.AppendFormat("'{0}'", item);
            }
            return sb.ToString();
        }


        /// <summary>
        /// 以,关联在一起 in查询所用
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string Join(this List<int> s)
        {
            if (s == null || s.Count == 0)
            {
                return "0";
            }
            StringBuilder sb = new StringBuilder();
            foreach (var item in s)
            {
                if (sb.Length > 0)
                {
                    sb.Append(",");
                }
                sb.AppendFormat("{0}", item);
            }
            return sb.ToString();
        }
    }
}
